using Emgu.CV.CvEnum;
using Emgu.CV;
using System.Drawing.Imaging;
using System.Drawing;
using System.Runtime.InteropServices;

namespace OK框自动提交
{
    public partial class Form1 : Form
    {
        private string clipNamePath = "D:\\皇榜.txt";
        bool started = false;
        private bool autoInput = false;
        Rectangle rectangle = new Rectangle(0, 0, 0, 0);
        public Form1()
        {
            InitializeComponent();

            Task.Run(() =>
            {
                while (true)
                {
                    if (!started)
                    {
                        Thread.Sleep(1000);
                        continue;
                    }
                    rectangle = GetMatchPos("ok.png");
                    if (rectangle.X > 0 && rectangle.Y > 0)
                    {
                        if (autoInput)
                        {
                            var inputRectangle = GetMatchPos("ok.png");
                            if (inputRectangle.X <= 0 && inputRectangle.Y <= 0)
                            {
                                Message($"未找到：放入框！");
                                Thread.Sleep(3000);
                                continue;
                            }
                            string clipName = File.ReadAllText(clipNamePath);
                            string clipPath = $"material\\{clipName}.png";
                            if (!File.Exists(Application.StartupPath + clipPath))
                            {
                                Message($"未找到：[{clipName}]相关素材！");
                                Thread.Sleep(3000);
                                continue;
                            }

                            var clipRectangle = GetMatchPos(clipPath);
                            if (clipRectangle.X <= 0 && clipRectangle.Y <= 0)
                            {
                                Message($"未找到：[{clipName}]！");
                                Thread.Sleep(3000);
                                continue;
                            }

                            //选择
                            SetCursorPos(clipRectangle.X, clipRectangle.Y);
                            MouseClickAt(new POINT { X = clipRectangle.X, Y = clipRectangle.Y });
                            Thread.Sleep(500);

                            //放入
                            SetCursorPos(inputRectangle.X, inputRectangle.Y);
                            MouseClickAt(new POINT { X = inputRectangle.X, Y = inputRectangle.Y });
                            Thread.Sleep(500);
                        }
                        //提交
                        SetCursorPos(rectangle.X, rectangle.Y);
                        MouseClickAt(new POINT { X = rectangle.X, Y = rectangle.Y });
                        Message($"点击坐标：X={rectangle.X} Y={rectangle.Y}");
                    }
                    else
                    {
                        Message($"未找到坐标！");
                    }
                    Thread.Sleep(3000);
                }
            });
        }

        private void Message(string msg)
        {
            try
            {
                this.Invoke(new Action(() =>
                {
                    try { label1.Text = msg; }
                    catch { }
                }));
            }
            catch { }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Run();
        }

        private void Run()
        {
            button1.Text = button1.Text == "开始(F7)" ? "停止(F7)" : "开始(F7)";
            started = button1.Text == "停止(F7)";
        }

        #region 截屏并找图
        /// <summary>
        /// 找图
        /// </summary>
        /// <param name="img1">大图</param>
        /// <param name="img2">小图</param>
        /// <returns></returns>
        public Rectangle GetMatchPos(string demoPng)
        {
            try
            {
                CaptureScreen();
                if (!File.Exists(Application.StartupPath + "compare.png"))
                {
                    return new Rectangle(0, 0, 0, 0);
                }
                Mat Src = CvInvoke.Imread(Application.StartupPath + "compare.png", ImreadModes.Grayscale);
                Mat Template = CvInvoke.Imread(Application.StartupPath + demoPng, ImreadModes.Grayscale);

                Mat MatchResult = new Mat();//匹配结果

                CvInvoke.MatchTemplate(Src, Template, MatchResult, TemplateMatchingType.CcoeffNormed);//使用相关系数法匹配
                Point max_loc = new Point();
                Point min_loc = new Point();
                double max = 0, min = 0;
                CvInvoke.MinMaxLoc(MatchResult, ref min, ref max, ref min_loc, ref max_loc);//获得极值信息
                Console.WriteLine(min + " " + max);
                if (max > 0.9 && max_loc.X > 0 && max_loc.Y > 0)
                {
                    max_loc.X = max_loc.X + Template.Size.Width / 2;
                    max_loc.Y = max_loc.Y + Template.Size.Height / 2;
                    return new Rectangle(max_loc, Template.Size);
                }
                else
                {
                    return new Rectangle(0, 0, 0, 0);
                }
            }
            catch (Exception ex)
            {
                return new Rectangle(0, 0, 0, 0);
            }
        }

        public void CaptureScreen()
        {
            // 创建一个和屏幕一样大小的Bitmap
            using (Bitmap bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height))
            {
                // 创建一个画板
                using (Graphics g = Graphics.FromImage(bmp))
                {
                    // 截取整个屏幕
                    g.CopyFromScreen(new Point(0, 0), new Point(0, 0), Screen.PrimaryScreen.Bounds.Size);
                }

                // 保存图片到文件
                bmp.Save(Application.StartupPath + "compare.png", ImageFormat.Png);
            }
        }
        #endregion

        #region 模拟鼠标移动点击
        [StructLayout(LayoutKind.Sequential)]
        public struct POINT
        {
            public int X;
            public int Y;

            public POINT(int x, int y)
            {
                this.X = x;
                this.Y = y;
            }
        }

        [DllImport("user32.dll")]
        static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, UIntPtr dwExtraInfo);

        private const uint MOUSEEVENTF_LEFTDOWN = 0x02;
        private const uint MOUSEEVENTF_LEFTUP = 0x04;

        public static void MouseClickAt(POINT location)
        {
            mouse_event(MOUSEEVENTF_LEFTDOWN, (uint)location.X, (uint)location.Y, 0, UIntPtr.Zero);
            mouse_event(MOUSEEVENTF_LEFTUP, (uint)location.X, (uint)location.Y, 0, UIntPtr.Zero);
        }

        [DllImport("user32.dll")]
        public static extern bool SetCursorPos(int X, int Y);
        #endregion

        private void Form1_Activated(object sender, EventArgs e)
        {
            HotKey.RegisterHotKey(Handle, 100, HotKey.KeyModifiers.None, Keys.F7);
        }

        private void Form1_Leave(object sender, EventArgs e)
        {
            HotKey.UnregisterHotKey(Handle, 100);
        }

        protected override void WndProc(ref Message m)
        {
            const int WM_HOTKEY = 0x0312;
            //按快捷键 
            switch (m.Msg)
            {
                case WM_HOTKEY:
                    switch (m.WParam.ToInt32())
                    {
                        case 100:
                            Run();
                            break;
                    }
                    break;
            }
            base.WndProc(ref m);
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            autoInput = checkBox1.Checked;
        }
    }
}